package com.iplant.aps.controller.aps;

import com.iplant.aps.service.APSService;
import com.iplant.aps.service.ASVService;
import com.iplant.aps.service.apsenum.aps.APSShiftPeriod;
import com.iplant.aps.service.po.aps.*;
import com.iplant.aps.service.po.aps.impPo.APSMonthShowPo;
import com.iplant.aps.service.po.oms.OMSOrder;
import com.iplant.aps.service.po.oms.OMSOutsourceOrder;
import com.iplant.aps.service.po.sch.APSMessage;
import com.iplant.base.po.OutResult;
import com.iplant.base.po.ServiceResult;
import com.iplant.base.po.excel.ExcelData;
import com.iplant.base.utils.RetCode;
import com.iplant.base.utils.excel.ExcelReader;
import com.iplant.base.utils.serializer.CloneTool;
import com.iplant.base.utils.general.StringUtils;
import com.iplant.basic.controller.BasicController;
import com.iplant.basic.service.po.bms.BMSEmployee;
import com.iplant.pdm.service.po.bop.FPCRoute;
import com.iplant.pdm.service.po.bop.FPCRoutePart;
import com.iplant.pdm.service.po.fmc.FMCLine;
import com.iplant.pdm.service.po.fpc.FPCPart;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/api/APSTaskPart")
public class APSTaskPartController extends BasicController<APSTaskPart> {
    private static final Logger logger = LoggerFactory.getLogger(APSTaskPartController.class);

    @Autowired
    APSService mAPSService;

    @Autowired
    ASVService mASVService;

    public APSTaskPartController() {
        super(APSTaskPart.class);
    }

    /**
     * 查询表格数据
     */
    @GetMapping("/TableInfoList")
    public Object TableInfoList(HttpServletRequest request) {
        Object wResult = new Object();
        try {


            BMSEmployee wLoginUser = GetSession(request);

            Calendar wStartTime = StringUtils.parseCalendar(request.getParameter("StartTime"));
            Calendar wEndTime = StringUtils.parseCalendar(request.getParameter("EndTime"));
            int wAPSShiftPeriod = StringUtils.parseInt(request.getParameter("APSShiftPeriod"));

            ServiceResult<List<Map<String, Object>>> wServiceResult = mAPSService.APS_QueryTableInfoList(wLoginUser,
                    wStartTime, wEndTime, wAPSShiftPeriod);

            if (StringUtils.isEmpty(wServiceResult.getFaultCode())) {
                wResult = GetResult(RetCode.SERVER_CODE_SUC, "", wServiceResult.Result, null);
            } else {
                wResult = GetResult(RetCode.SERVER_CODE_ERR, wServiceResult.getFaultCode());
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
            wResult = GetResult(RetCode.SERVER_CODE_ERR, ex.toString());
        }
        return wResult;
    }

    /**
     * 自动排程(工位)
     */
    @PostMapping("/AutoScheduling")
    public Object AutoScheduling(HttpServletRequest request, @RequestBody Map<String, Object> wParam) {
        Map<String, Object> wResult = new HashMap<>();
        try {
            BMSEmployee wLoginUser = GetSession(request);

            // 排程订单
            List<OMSOrder> wOrderList = CloneTool.CloneArray(wParam.get("OrderList"), OMSOrder.class);
            if (wOrderList == null || wOrderList.size() == 0) {
                return GetResult(RetCode.SERVER_CODE_ERR, RetCode.SERVER_RST_ERROR_OUT);
            }
            //检查数据
            if (wOrderList.stream().anyMatch(p -> p.RouteID == 0)) {
                OMSOrder wCheckOrder = wOrderList.stream().filter(p -> p.RouteID == 0).findFirst().get();
                return GetResult(RetCode.SERVER_CODE_ERR, StringUtils.Format("提示：订单【{0}】未设置工艺路线!",
                        wCheckOrder.Code));
            }

            // 排程性质
            APSShiftPeriod wShiftPeriod = APSShiftPeriod
                    .getEnumType(StringUtils.parseInt(wParam.get("APSShiftPeriod")));
            //排程时间段
            Calendar wStartTime = StringUtils.parseCalendar(wParam.get("StartTime"));
            Calendar wEndTime = StringUtils.parseCalendar(wParam.get("EndTime"));
            //工艺允许的延时（h）
            int wAllowTechDelayHour = StringUtils.parseInt(wParam.get("AllowTechDelayHour"));
            //是否强制检查物料
            int wCheckMaterial = StringUtils.parseInt(request.getParameter("CheckMaterial"));
            boolean wCheckMaterialBool = wCheckMaterial == 1;
            // 自动排程
            ServiceResult<List<APSTaskPart>> wServerRst = mAPSService.APS_AutoTaskPart(wLoginUser, wOrderList,
                    wShiftPeriod, wAllowTechDelayHour, wCheckMaterialBool, wStartTime, wEndTime);

            if (StringUtils.isEmpty(wServerRst.getFaultCode())) {
                wResult = GetResult(RetCode.SERVER_CODE_SUC, "", wServerRst.Result, null);
                for (String wKey : wServerRst.CustomResult.keySet()) {
                    SetResult(wResult, wKey, wServerRst.CustomResult.get(wKey));
                }
            } else {
                wResult = GetResult(RetCode.SERVER_CODE_ERR, wServerRst.getFaultCode());
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
            wResult = GetResult(RetCode.SERVER_CODE_ERR, ex.toString());
        }
        return wResult;
    }

    /**
     * 手动排程
     */
    @PostMapping("/ManualScheduling")
    public Object ManualScheduling(HttpServletRequest request, @RequestBody Map<String, Object> wParam) {
        Map<String, Object> wResult = new HashMap<>();
        try {
            BMSEmployee wLoginUser = GetSession(request);

            if (!wParam.containsKey("data"))
                return GetResult(RetCode.SERVER_CODE_ERR, RetCode.SERVER_RST_ERROR_OUT);

            Map<String, Object> wDataParam = CloneTool.Clone(wParam.get("data"), Map.class);

            List<APSTaskPart> wCheckTaskList = CloneTool.CloneArray(wDataParam.get("CheckTaskList"), APSTaskPart.class);
            List<OMSOrder> wOrderList = CloneTool.CloneArray(wDataParam.get("OrderList"), OMSOrder.class);
            APSShiftPeriod wShiftPeriod = APSShiftPeriod
                    .getEnumType(CloneTool.Clone(wDataParam.get("APSShiftPeriod"), Integer.class));
            Calendar wStartTime = CloneTool.Clone(wDataParam.get("StartTime"), Calendar.class);
            Calendar wEndTime = CloneTool.Clone(wDataParam.get("EndTime"), Calendar.class);
            int wWorkDay = CloneTool.Clone(wDataParam.get("WorkDay"), Integer.class);

            // 工位任务列表
            List<APSTaskPart> wOrderPartIssuedList = new ArrayList<>();

            // 委外订单列表
            List<OMSOutsourceOrder> wOutsourceOrderList = new ArrayList<>();

            // 工位工时列表
            List<APSManuCapacity> wManuCapacityList = new ArrayList<>();

            // 获取工艺路径
            Map<Integer, List<FPCRoutePart>> wRoutePartListMap = new HashMap<>();


            // 工位赋值
            List<FPCPart> wFPCPartList = new ArrayList<>();

            // 手动排程
            ServiceResult<List<APSMessage>> wServiceResult = mAPSService.APS_CheckTaskPart(wLoginUser, wOrderList,
                    wCheckTaskList, wShiftPeriod, wOrderPartIssuedList, wOutsourceOrderList, wStartTime, wEndTime,
                    wRoutePartListMap, wManuCapacityList, wWorkDay);

            // 甘特图Tip生成

            // 返回Tree型数据
            // 产线列表
            List<FMCLine> wLineList = new ArrayList<>();

            // 工位列表
            List<FPCPart> wPartList = new ArrayList<>();

            List<APSTaskPart> wTreeList = new ArrayList<>();

            // 表格数据
            List<Map<String, Object>> wTableMap = new ArrayList<>();
            List<FPCPart> wStationList = new ArrayList<>();

            SetResult(wResult, "TableInfoList", wTableMap);
            SetResult(wResult, "OrderColumn", wStationList);

            wResult = GetResult(RetCode.SERVER_CODE_SUC, "", wServiceResult.Result, null);
            SetResult(wResult, "TreeList", wTreeList);
            SetResult(wResult, "TaskList", wCheckTaskList);
            Calendar wMaxTime = Calendar.getInstance();
            SetResult(wResult, "MaxTime", wMaxTime);
        } catch (Exception ex) {
            logger.error(ex.toString());
            wResult = GetResult(RetCode.SERVER_CODE_ERR, ex.toString());
        }
        return wResult;
    }

    /**
     * 保存排程结果
     */
    @PostMapping("/SaveSchedulingVersion")
    public Object SaveSchedulingVersion(HttpServletRequest request, @RequestBody Map<String, Object> wParam) {
        Map<String, Object> wResult = new HashMap<>();
        try {
            BMSEmployee wLoginUser = GetSession(request);

            List<APSTaskPart> wTaskPartList = CloneTool.CloneArray(wParam.get("TaskPartList"), APSTaskPart.class);

            if (wTaskPartList == null || wTaskPartList.size() == 0)
                return GetResult(RetCode.SERVER_CODE_ERR, RetCode.SERVER_RST_ERROR_OUT);

            ServiceResult<Integer> wServiceResult = mASVService.APS_SaveSchedulingVersion(wLoginUser, wTaskPartList,
                    wTaskPartList.get(0).ShiftPeriod);

            if (StringUtils.isEmpty(wServiceResult.getFaultCode())) {
                wResult = GetResult(RetCode.SERVER_CODE_SUC, "", wTaskPartList, wServiceResult.Result);
            } else {
                wResult = GetResult(RetCode.SERVER_CODE_ERR, wServiceResult.getFaultCode());
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
            wResult = GetResult(RetCode.SERVER_CODE_ERR, ex.toString());
        }
        return wResult;
    }

    /**
     * 获取树形数据
     */
    @PostMapping("/TreeList")
    public Object TreeList(HttpServletRequest request, @RequestBody Map<String, Object> wParam) {
        Map<String, Object> wResult = new HashMap<>();
        try {
            BMSEmployee wLoginUser = GetSession(request);

            List<APSMessage> wMessageList = CloneTool.CloneArray(wParam.get("MessageList"), APSMessage.class);
            List<APSTaskPart> wTaskPartList = CloneTool.CloneArray(wParam.get("TaskPartList"), APSTaskPart.class);

            // 返回Tree型数据
            // 产线列表
            List<FMCLine> wLineList = new ArrayList<>();

            // 获取工艺路径
            Map<Integer, List<FPCRoutePart>> wRoutePartListMap = new HashMap<>();

            Map<Integer, List<FPCRoutePart>> wRouteMap = new HashMap<>();

            // 工位列表
            List<FPCPart> wPartList = new ArrayList<>();

            int wFlag = 1;
            int wOrderFlag = 1;
            List<APSTaskPart> wTreeList = new ArrayList<>();

            // 树形结果
            wResult = GetResult(RetCode.SERVER_CODE_SUC, "", wTreeList, null);
            // 表格数据

            List<Map<String, Object>> wTableMap = new ArrayList<>();
            List<FPCPart> wStationList = new ArrayList<>();

            SetResult(wResult, "TableInfoList", wTableMap);
            SetResult(wResult, "OrderColumn", wStationList);

            // 获取去重后的订单工艺路线
            List<FPCRoute> wRouteList = new ArrayList<>();

            SetResult(wResult, "RouteList", wRouteList);
        } catch (Exception ex) {
            logger.error(ex.toString());
            wResult = GetResult(RetCode.SERVER_CODE_ERR, ex.toString());
        }
        return wResult;
    }

    /**
     * 获取表格数据
     */
    @PostMapping("/TableList")
    public Object TableList(HttpServletRequest request, @RequestBody Map<String, Object> wParam) {
        Map<String, Object> wResult = new HashMap<>();
        try {
            BMSEmployee wLoginUser = GetSession(request);

            List<OMSOrder> wOrderList = CloneTool.CloneArray(wParam.get("OrderList"), OMSOrder.class);
            List<APSTaskPart> wTaskPartList = CloneTool.CloneArray(wParam.get("TaskPartList"), APSTaskPart.class);
            Integer wType = StringUtils.parseInt(wParam.get("Type"));

            // 订单排序
            List<Integer> wList = wOrderList.stream().map(p -> p.ID).distinct().collect(Collectors.toList());

            OutResult<Integer> wErrorCode = new OutResult<>(0);
            wOrderList = new ArrayList<>();

            // 工位任务排序
            wTaskPartList = new ArrayList<>();

            List<Map<String, Object>> wTableMap = new ArrayList<>();
            Map<String, Object> wHeadMap = new HashMap<>();
            List<FPCPart> wStationList = new ArrayList<>();

            wTableMap.add(wHeadMap);

            wResult = GetResult(RetCode.SERVER_CODE_SUC, "", null, null);
            SetResult(wResult, "TableInfoList", wTableMap);
            SetResult(wResult, "OrderColumn", wStationList);
        } catch (Exception ex) {
            logger.error(ex.toString());
            wResult = GetResult(RetCode.SERVER_CODE_ERR, ex.toString());
        }
        return wResult;
    }

    /**
     * 月计划导入
     */
    @PostMapping("/MonthlyPlanImport")
    public Object MonthlyPlanImport(HttpServletRequest request, @RequestParam("file") MultipartFile[] files) {
        Object wResult = new Object();
        try {
            BMSEmployee wLoginUser = GetSession(request);

            if (files.length == 0) {
                return GetResult(RetCode.SERVER_CODE_ERR, "提示：没有要上传的Excel文件！");
            }

            ServiceResult<Integer> wServiceResult = new ServiceResult<>();
            ServiceResult<ExcelData> wExcelData = null;
            String wOriginalFileName = null;
            for (MultipartFile wMultipartFile : files) {
                wOriginalFileName = wMultipartFile.getOriginalFilename();

                assert wOriginalFileName != null;
                if (wOriginalFileName.contains("xlsx"))
                    wExcelData = ExcelReader.getInstance().readMultiSheetExcel(wMultipartFile.getInputStream(),
                            wOriginalFileName, "xlsx", 1000000);
                else if (wOriginalFileName.contains("xls"))
                    wExcelData = ExcelReader.getInstance().readMultiSheetExcel(wMultipartFile.getInputStream(),
                            wOriginalFileName, "xls", 1000000);

                assert wExcelData != null;
                if (StringUtils.isNotEmpty(wExcelData.FaultCode)) {
                    wResult = GetResult(RetCode.SERVER_CODE_ERR, wExcelData.FaultCode);
                    return wResult;
                }

                wServiceResult = mAPSService.APS_MonthlyPlanImport(wLoginUser, wExcelData.Result);

                if (!StringUtils.isEmpty(wServiceResult.FaultCode))
                    break;
            }

            if (StringUtils.isEmpty(wServiceResult.FaultCode)) {
                wResult = GetResult(RetCode.SERVER_CODE_SUC, "导入成功!", null, null);
            } else {
                wResult = GetResult(RetCode.SERVER_CODE_ERR, wServiceResult.FaultCode);
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
            wResult = GetResult(RetCode.SERVER_CODE_ERR, ex.toString());
        }
        return wResult;
    }

    /**
     * 获取甘特图数据
     */
    @PostMapping("/QueryGanttData")
    public Object QueryGanttData(HttpServletRequest request, @RequestBody Map<String, Object> wParam) {
        Map<String, Object> wResult = new HashMap<String, Object>();
        try {
            BMSEmployee wLoginUser = GetSession(request);

            // 获取参数
            List<APSTaskPart> wAPSTaskPartList = CloneTool.CloneArray(wParam.get("data"), APSTaskPart.class);
            if (wAPSTaskPartList == null || wAPSTaskPartList.size() == 0) {
                return GetResult(RetCode.SERVER_CODE_ERR, RetCode.SERVER_RST_ERROR_OUT);
            }

            ServiceResult<Integer> wServiceResult = mAPSService.APS_QueryGanttData(wLoginUser, wAPSTaskPartList);

            if (StringUtils.isEmpty(wServiceResult.FaultCode)) {
                wResult = GetResult(RetCode.SERVER_CODE_SUC, "", wServiceResult.Result, null);
                for (String wKey : wServiceResult.CustomResult.keySet()) {
                    SetResult(wResult, wKey, wServiceResult.CustomResult.get(wKey));
                }
            } else {
                wResult = GetResult(RetCode.SERVER_CODE_ERR, wServiceResult.FaultCode);
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
            wResult = GetResult(RetCode.SERVER_CODE_ERR, ex.toString());
        }
        return wResult;
    }

    /**
     * 周计划导入
     */
    @PostMapping("/WeeklyPlanImport")
    public Object WeeklyPlanImport(HttpServletRequest request, @RequestParam("file") MultipartFile[] files) {
        Object wResult = new Object();
        try {
            BMSEmployee wLoginUser = GetSession(request);

            if (files.length == 0) {
                return GetResult(RetCode.SERVER_CODE_ERR, "提示：没有要上传的Excel文件！");
            }

            ServiceResult<Integer> wServiceResult = new ServiceResult<>();
            ServiceResult<ExcelData> wExcelData = null;
            String wOriginalFileName = null;
            for (MultipartFile wMultipartFile : files) {
                wOriginalFileName = wMultipartFile.getOriginalFilename();

                assert wOriginalFileName != null;
                if (wOriginalFileName.contains("xlsx"))
                    wExcelData = ExcelReader.getInstance().readMultiSheetExcel(wMultipartFile.getInputStream(),
                            wOriginalFileName, "xlsx", 1000000);
                else if (wOriginalFileName.contains("xls"))
                    wExcelData = ExcelReader.getInstance().readMultiSheetExcel(wMultipartFile.getInputStream(),
                            wOriginalFileName, "xls", 1000000);

                assert wExcelData != null;
                if (StringUtils.isNotEmpty(wExcelData.FaultCode)) {
                    wResult = GetResult(RetCode.SERVER_CODE_ERR, wExcelData.FaultCode);
                    return wResult;
                }

                wServiceResult = mAPSService.APS_WeeklyPlanImport(wLoginUser, wExcelData.Result);

                if (!StringUtils.isEmpty(wServiceResult.FaultCode))
                    break;
            }

            if (StringUtils.isEmpty(wServiceResult.FaultCode)) {
                wResult = GetResult(RetCode.SERVER_CODE_SUC, "导入成功!", null, null);
            } else {
                wResult = GetResult(RetCode.SERVER_CODE_ERR, wServiceResult.FaultCode);
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
            wResult = GetResult(RetCode.SERVER_CODE_ERR, ex.toString());
        }
        return wResult;
    }

    /**
     * 月计划数据展示转化
     */
    @GetMapping("/MonthDataChangeToShow")
    public Object MonthDataChangeToShow(HttpServletRequest request) {
        Object wResult = new Object();
        try {
            BMSEmployee wLoginUser = GetSession(request);

            // 获取参数
            int wSchedulingVersionBPMID = StringUtils.parseInt(request.getParameter("SchedulingVersionBPMID"));
            if (wSchedulingVersionBPMID <= 0) {
                return GetResult(RetCode.SERVER_CODE_ERR, RetCode.SERVER_RST_ERROR_OUT);
            }

            ServiceResult<List<APSMonthShowPo>> wServiceResult =
                    mAPSService.APS_QueryMonthDataChangeToShow(wLoginUser, wSchedulingVersionBPMID);

            if (StringUtils.isEmpty(wServiceResult.FaultCode)) {
                wResult = GetResult(RetCode.SERVER_CODE_SUC, "", wServiceResult.Result, null);
            } else {
                wResult = GetResult(RetCode.SERVER_CODE_ERR, wServiceResult.FaultCode);
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
            wResult = GetResult(RetCode.SERVER_CODE_ERR, ex.toString(), null, null);
        }
        return wResult;
    }
}
